package client_listen_update_files;

import java.io.IOException;
import java.io.ObjectInputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import dropbox.common.Command;
/**
 * in charge to get updates from server about files
 * and folders to client
 * 
 * @author Yoav
 *
 */
public class GetUpdatedFiles implements Runnable{
	
	//indicates if we need to stop
	private volatile boolean stop;
	//holds server address
	private String address=null;
	//holds file action at client
	private ClientFileAction clientFileAction = new ClientFileAction();
	
	/**
	 * constructor
	 * @param address server's address
	 */
	public GetUpdatedFiles(String address) {
		this.address=address;
		stop=true;
	}
	
	/*
	 * get interceptor instance ready to use
	 * @param userName user's name
	 * @param password user's password
	 * @return HttpRequestinterceptor ready to use
	 */
	private HttpRequestInterceptor getInterWithUsrNPass(final String userName,final String password){
		return new HttpRequestInterceptor() {
			   @Override
			   public void process(HttpRequest req, HttpContext context)
			     throws HttpException, IOException {
			    req.addHeader(new BasicScheme()
			     .authenticate(new UsernamePasswordCredentials(userName,password), req));			    
			   }
		 };
	}
	
	/*
	 * ask server for new updates, keep getting updates 
	 * until serivce has stopped
	 * 
	 * @param userName - user's name
	 * @param password - user's password
	 */
	private void askUpdatedFiles(String userName,String password){
		
		stop=false;
		/*set http client and http post in order to send through post method
	 	request to server also insert user name and password in header*/
		DefaultHttpClient httpclient = new DefaultHttpClient();
	    httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
	    HttpRequestInterceptor preemtiveAuth = getInterWithUsrNPass(userName,password);
		httpclient.addRequestInterceptor(preemtiveAuth,0);
		
	    HttpPost httppost = new HttpPost(address);
	    
	    HttpResponse response;
	    HttpEntity entity=null;
	    
	    try {
	    	//execute request
	    	response = httpclient.execute(httppost);
	    	while (!stop){
	    		
	    		//get updates from server
	    		entity = response.getEntity();			
	    		ObjectInputStream ois = new ObjectInputStream(entity.getContent());
	    		Command command  = null;
	    		
	    		try{
	    			//get command from server
	    			command = (Command)ois.readObject();
	    		}catch (IOException e){
	    			//can't read object	    			
	    		}catch (ClassNotFoundException e){
	    			//can't find class
	    		}
			
	    		if (!stop && command!=null){
	    			//set file action in received command
	    			command.setAction(clientFileAction);
	    			//execute command
	    			command.execute();
	    		}
	    	}
	    	//end communication
	    	 if (entity!=null){
	 			EntityUtils.consume(entity);	 		
	 		}
	    	 httpclient.getConnectionManager().shutdown();
	    	 
	    	
		} catch (IOException e1) {			
		}
	}
	/**
	 * stop getting updates from server
	 */
	public void stop (){
		stop=true;
	}
	
	@Override
	public void run() {		
		askUpdatedFiles(ConfigManager.get().getUserName(),ConfigManager.get().getPassword());
		
	}
}
